﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using WJP.Context;

namespace WJP.DataPortal
{
    /// <summary>
    /// 数据门户
    /// 内部封装了对数据层的调用，如果是远程，则使用对应的代理来访问，这使得单机版、网络版的调用完全一致。
    /// </summary>
    internal static class PortalApi
    {
        private static Type _proxyType;

        /// <summary>
        /// 使用门户查询
        /// </summary>
        /// <param name="objectType"></param>
        /// <param name="criteria"></param>
        /// <returns></returns>
        public static object Fetch(Type objectType, object criteria)
        {
            try
            {
                ++PlatformEnvironment.ThreadPortalCount;
                IDataPortalProxy dataPortalProxy = GetDataPortalProxy();//ClientProxy
                DataPortalContext dataPortalContext = CreateDataPortalContext();
                return ReadServerResult(dataPortalProxy.Fetch(objectType, criteria, dataPortalContext));
            }
            finally
            {
                --PlatformEnvironment.ThreadPortalCount;
            }
        }

        public static object Update(object obj)
        {
            try
            {
                ++PlatformEnvironment.ThreadPortalCount;
                IDataPortalProxy dataPortalProxy = PortalApi.GetDataPortalProxy();
                DataPortalContext dataPortalContext = PortalApi.CreateDataPortalContext();
                return PortalApi.ReadServerResult(dataPortalProxy.Update(obj, dataPortalContext));
            }
            finally
            {
                --PlatformEnvironment.ThreadPortalCount;
            }
        }

        /// <summary>
        /// 根据配置文件创建数据门户代理
        /// </summary>
        /// <returns></returns>
        private static IDataPortalProxy GetDataPortalProxy()
        {
            if (_proxyType == null)
                _proxyType = Type.GetType(PlatformEnvironment.Configuration.Section.DataPortalProxy, true, true);
            return Activator.CreateInstance(_proxyType) as IDataPortalProxy;
        }

        /// <summary>
        /// 读取服务端返回的结果
        /// </summary>
        /// <param name="result"></param>
        /// <returns></returns>
        private static object ReadServerResult(DataPortalResult result)
        {
            DistributionContext.SetGlobalContext(result.GlobalContext);
            return result.ReturnObject;
        }

        /// <summary>
        /// 创建数据门户上下文
        /// </summary>
        /// <returns></returns>
        private static DataPortalContext CreateDataPortalContext()
        {
            return new DataPortalContext()
            {
                //TODO:Principal = PlatformEnvironment.Principal
                ClientCulture = Thread.CurrentThread.CurrentCulture.Name,
                ClientUICulture = Thread.CurrentThread.CurrentUICulture.Name,
                ClientContext = DistributionContext.GetClientContext(),
                GlobalContext = DistributionContext.GetGlobalContext()
            };
        }
    }
}
